//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "ModelDetailAccuracy.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fstream>
#include <iostream>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#define MAX_SIZE 500000
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ModelDetailAccuracy::ModelDetailAccuracy () {

  this->className         = new String ();
  this->rocArea           = 0;
  this->fMeasure          = 0;
  this->recall            = 0;
  this->precision         = 0;
  this->falsePositiveRate = 0;
  this->truePositiveRate  = 0;
  this->toString          = new String ();

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ModelDetailAccuracy::ModelDetailAccuracy (const ModelDetailAccuracy& modelDetailAccuracy) {

  this->className         = new String (modelDetailAccuracy.className);
  this->rocArea           = modelDetailAccuracy.rocArea;
  this->fMeasure          = modelDetailAccuracy.fMeasure;
  this->recall            = modelDetailAccuracy.recall;
  this->precision         = modelDetailAccuracy.precision;
  this->falsePositiveRate = modelDetailAccuracy.falsePositiveRate;
  this->truePositiveRate  = modelDetailAccuracy.truePositiveRate;
  this->toString          = new String (modelDetailAccuracy.toString);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ModelDetailAccuracy::ModelDetailAccuracy (const ModelDetailAccuracy* modelDetailAccuracy) {

  this->className         = new String (modelDetailAccuracy->className);
  this->rocArea           = modelDetailAccuracy->rocArea;
  this->fMeasure          = modelDetailAccuracy->fMeasure;
  this->recall            = modelDetailAccuracy->recall;
  this->precision         = modelDetailAccuracy->precision;
  this->falsePositiveRate = modelDetailAccuracy->falsePositiveRate;
  this->truePositiveRate  = modelDetailAccuracy->truePositiveRate;
  this->toString          = new String (modelDetailAccuracy->toString);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ModelDetailAccuracy::~ModelDetailAccuracy () {

  if (this->className        ) delete this->className;
  if (this->toString         ) delete this->toString;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ModelDetailAccuracy::ClassName (String* className) {

  if (className)
    *(this->className) = *className;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ModelDetailAccuracy::RocArea (float rocArea) {

  this->rocArea = rocArea;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ModelDetailAccuracy::FMeasure (float fMeasure) {

  this->fMeasure = fMeasure;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ModelDetailAccuracy::Recall (float recall) {

  this->recall = recall;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ModelDetailAccuracy::Precision (float precision) {

  this->precision = precision;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ModelDetailAccuracy::FalsePositiveRate (float falsePositiveRate) {

  this->falsePositiveRate = falsePositiveRate;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ModelDetailAccuracy::TruePositiveRate (float truePositiveRate) {

  this->truePositiveRate = truePositiveRate;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//

String* ModelDetailAccuracy::ClassName (void) {

  return this->className;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float ModelDetailAccuracy::RocArea (void) {

  return this->rocArea;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float ModelDetailAccuracy::FMeasure (void) {

  return this->fMeasure;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float ModelDetailAccuracy::Recall (void) {

  return this->recall;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float ModelDetailAccuracy::Precision (void) {

  return this->precision;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float ModelDetailAccuracy::FalsePositiveRate (void) {

  return this->falsePositiveRate;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float ModelDetailAccuracy::TruePositiveRate (void) {

  return this->truePositiveRate;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* ModelDetailAccuracy::ToString (int numberSpaces) {

  char buffer [MAX_SIZE];
  char spaces [MAX_SIZE];
  
  for (int i = 0; i < numberSpaces; i++)
    spaces[i] = ' ';
  spaces[numberSpaces] = '\0';
  
  this->toString->In(spaces);
  
  sprintf(buffer, "                 %5.3f     %5.3f      %5.3f     %5.3f     %5.3f   %6.3f    %s\0", this->truePositiveRate, 
                                                                                                     this->falsePositiveRate, 
                                                                                                     this->precision, 
                                                                                                     this->recall, 
                                                                                                     this->fMeasure, 
                                                                                                     this->rocArea, 
                                                                                                     this->className->Out());
  this->toString->Add(buffer);
  
  return this->toString;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* ModelDetailAccuracy::ToString (void) {

  return this->ToString(0);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* ModelDetailAccuracy::ToStringHeader (void) {

  char buffer [MAX_SIZE];
  
  sprintf(buffer, "               TP Rate   FP Rate   Precision   Recall  F-Measure   ROC Area  Class\0");
  this->toString->In(buffer);
  
  return this->toString;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* ModelDetailAccuracy::ToStringWeightedLine (int numberSpaces) {

  char buffer [MAX_SIZE];
  char spaces [MAX_SIZE];
  
  for (int i = 0; i < numberSpaces; i++)
    spaces[i] = ' ';
  spaces[numberSpaces] = '\0';
  
  this->toString->In(spaces);
  
  sprintf(buffer, "Weighted Avg.    %5.3f     %5.3f      %5.3f     %5.3f     %5.3f   %6.3f\0", this->truePositiveRate, 
                                                                                               this->falsePositiveRate, 
                                                                                               this->precision, 
                                                                                               this->recall, 
                                                                                               this->fMeasure, 
                                                                                               this->rocArea);
  this->toString->Add(buffer);
  
  return this->toString;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* ModelDetailAccuracy::ToStringWeightedLine (void) {

  return this->ToStringWeightedLine(0);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool ModelDetailAccuracy::LoadFromLine (String* line) {

  if (!line || !line->Length())
    return false;
  
  char* parts        = NULL;
  bool  condWeighted = false;
  
  if (strstr(line->Out(), "Weighted Avg.")) {
    parts = strtok(line->Out(), ".");
    if (!parts) return false;
    condWeighted = true;
  }
  
  parts = strtok((strstr(line->Out(), "Weighted Avg.")?NULL:line->Out()), " ");
  if (!parts) return false;
  this->truePositiveRate = atof(parts);
  
  parts = strtok(NULL, " ");
  if (!parts) return false;
  this->falsePositiveRate = atof(parts);
  
  parts = strtok(NULL, " ");
  if (!parts) return false;
  this->precision = atof(parts);
  
  parts = strtok(NULL, " ");
  if (!parts) return false;
  this->recall = atof(parts);
  
  parts = strtok(NULL, " ");
  if (!parts) return false;
  this->fMeasure = atof(parts);
  
  parts = strtok(NULL, " ");
  if (!parts) return false;
  this->rocArea = atof(parts);
  
  if (!condWeighted) {
    parts = strtok(NULL, " ");
    if (!parts) return false;
    this->className->In(parts);
  }
  
  return true;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ModelDetailAccuracy ModelDetailAccuracy::operator= (const ModelDetailAccuracy& modelDetailAccuracy) {

  *(this->className)      = *(modelDetailAccuracy.className);
  this->rocArea           = modelDetailAccuracy.rocArea;
  this->fMeasure          = modelDetailAccuracy.fMeasure;
  this->recall            = modelDetailAccuracy.recall;
  this->precision         = modelDetailAccuracy.precision;
  this->falsePositiveRate = modelDetailAccuracy.falsePositiveRate;
  this->truePositiveRate  = modelDetailAccuracy.truePositiveRate;
  *(this->toString)       = *(modelDetailAccuracy.toString);

  return *this;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
